package com.redis.schedule;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.redis.bean.MPost;
import com.redis.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.scheduling.annotation.Scheduled;
   import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Component
   public class ScheduledTasks {

    @Autowired
    private RedisUtil redisUtil;

       @Scheduled(cron = "0 0 * * * ?") // 每小时执行一次
       public void runEveryHour() {
           System.out.println("定时任务每小时执行一次：" + System.currentTimeMillis());
       }

//       @Scheduled(initialDelay = 1000, fixedRate = 10000000) // 每5秒执行一次
       public void runEveryFiveSeconds() {
           System.out.println("定时任务执行一次：" + System.currentTimeMillis());
            //获取  7天的文章
        List<MPost> posts  =  this.generatePostsForLastSevenDays();
            //  获取到7天前的以及按照这几个查询，不需要全部查询
            //  初始化文章的总评论
            for  (MPost  post  :  posts)  {
                    //  设置  key
//                    String  key  =  "day:rank:"  +  DateUtil.format(post.getCreated(),  DatePattern.PURE_DATE_FORMAT);
                String key = "{day:rank}:" + DateUtil.format(post.getCreated(), DatePattern.PURE_DATE_FORMAT) ;
                    //  缓存进去的评论数量
                    redisUtil.zSet(key,  post.getId(),  post.getCommentCount());
                    //设置自动过期  7天过期
                    long  between  =  DateUtil.between(new Date(),  post.getCreated(),  DateUnit.DAY);
                    long  expireTime  =  (7  -  between)  *  24  *  60  *  60;  //  有效  时间

                    redisUtil.expire(key,  expireTime);
                    //  缓存文章的一些基本信息
                    this.hashCachePost(post,  expireTime);
            }
            //  做并集
            this.zunionAndStore();
            //查询结果
           Set<ZSetOperations.TypedTuple<Object>> zSetRank = redisUtil.getZSetRank("{day:rank}", 0, -1);
           System.out.println(zSetRank);
       }

    public static List<MPost> generatePostsForLastSevenDays() {
        List<MPost> posts = new ArrayList<>();
        Random random = new Random();

        ZonedDateTime now = ZonedDateTime.now(ZoneId.systemDefault());
        for (int i = 0; i < 7; i++) {
            ZonedDateTime zonedDateTime = now.minusDays(7 - i);
            Date createdDate = Date.from(zonedDateTime.toInstant());
            MPost post = new MPost(
                    (long) (i + 1),
                    "文章标题 " + (i + 1),
                    (long) (random.nextInt(100) + 1),
                    random.nextInt(50) + 1,
                    random.nextInt(500) + 1,
                    createdDate
            );
            posts.add(post);
        }
        System.out.println(posts.toString());
        return posts;
    }


//       @Scheduled(initialDelay = 10000, fixedRate = 10000) // 初始延迟10秒后，每隔10秒执行一次
//       public void runWithInitialDelayAndFixedRate() {
//           System.out.println("定时任务初始延迟10秒后，每隔10秒执行一次：" + System.currentTimeMillis());
//       }
       
         /**
            *  文章每周评论数量并集操作
            **/
                 private  void  zunionAndStore()  {
//          String  destkey  =  "{day:rank:"  +  DateUtil.format(new  Date(),  DatePattern.PURE_DATE_FORMAT+"}");
                     String destkey = "{day:rank}:" + DateUtil.format(new  Date(), DatePattern.PURE_DATE_FORMAT) ;

                     //  设置并集后的新的  key
          String  newkey  =  "{day:rank}";
                     List<String>  otherKeys  =  new  ArrayList<>();
          //  计算7天的
          for  (int  i  =  -6;  i  <  0;  i++)  {
              String  temp  =  "{day:rank}:"  +  DateUtil.format(DateUtil.offsetDay(new  Date(),  i),  DatePattern.PURE_DATE_FORMAT);
//              temp=wrapWithBraces(temp);
                  otherKeys.add(temp);
          }

          redisUtil.zUnionAndStore(destkey,  otherKeys,  newkey);
  }

    private static String wrapWithBraces(String str) {
        return "{" + str + "}";
    }
  /**
     *  文章作者缓存
     **/
          private  void  hashCachePost(MPost  post,  long  expireTime)  {
          //  设置  key
          String  key  =  "{rank:post}:"  +  post.getId();
          //  判断存在不存在
          boolean  hasKey  =  redisUtil.hasKey(key);
          if  (!hasKey)  {
                  //  就存到缓存里面
                  redisUtil.hset(key,  "post:id",  post.getId(),  expireTime);
                  redisUtil.hset(key,  "post:title",  post.getTitle(),  expireTime);
                  redisUtil.hset(key,  "post:commentCount",  post.getCommentCount(),  expireTime);

          }
  }
       
   }
   